

import chisel3._
import chisel3.util._

// S011HD1P_X32Y2D128 from SoC team
trait SramParameters {
  val SramAddrWidth = 6
  val SramDepth = 64
  val SramDataWidth = 128
}

// ref: https://github.com/OSCPU/ysyxSoC
class S011HD1P_X32Y2D128 extends BlackBox with HasBlackBoxInline with SramParameters {
  val io = IO(new Bundle {
    val CLK = Input(Clock())
    val CEN = Input(Bool())
    val WEN = Input(Bool())
    val A = Input(UInt(SramAddrWidth.W))
    val D = Input(UInt(SramDataWidth.W))
    val Q = Output(UInt(SramDataWidth.W))
  })
  //addResource("/vsrc/S011HD1P_X32Y2D128.v")

  setInline("S011HD1P_X32Y2D128.v",
            """
      module S011HD1P_X32Y2D128(
          Q, CLK, CEN, WEN, A, D
      );
      parameter Bits = 128;
      parameter Word_Depth = 64;
      parameter Add_Width = 6;

      output  reg [Bits-1:0]      Q;
      input                   CLK;
      input                   CEN;
      input                   WEN;
      input   [Add_Width-1:0] A;
      input   [Bits-1:0]      D;

      reg [Bits-1:0] ram [0:Word_Depth-1];
      always @(posedge CLK) begin
          if(!CEN && !WEN) begin
              ram[A] <= D;
          end
          Q <= !CEN && WEN ? ram[A] : {4{$random}};
      end

      endmodule
            """)

}

class Sram(id: Int) extends Module with SramParameters {
  val io = IO(new Bundle {
    val en = Input(Bool())
    val wen = Input(Bool())
    val addr = Input(UInt(SramAddrWidth.W))
    val wdata = Input(UInt(SramDataWidth.W))
    val rdata = Output(UInt(SramDataWidth.W))
  })

  val sram = Module(new S011HD1P_X32Y2D128)
  sram.io.CLK := clock
  sram.io.CEN := !io.en
  sram.io.WEN := !io.wen
  sram.io.A := io.addr
  sram.io.D := io.wdata
  io.rdata := sram.io.Q

}
